#pragma once

#include "Interpreter.h"

#include <stack>
#include <stdexcept>
#include <string>

class Parser
{
public:
    int execute(const std::string &message)
    {
        std::stack<char> operators;
        std::stack<int>  operands;

        int tempNum = 0;
        for (int i = 0; i < message.size(); i++) {
            if (message.at(i) >= '0' && message.at(i) <= '9') {
                tempNum = tempNum * 10 + message.at(i) - '0';
            } else {
                if (tempNum != 0) {
                    operands.push(tempNum);
                    tempNum = 0;
                }

                if (message.at(i) == '+' || message.at(i) == '-') {
                    if (!operators.empty())
                        processOperator(operators, operands);
                    operators.push(message.at(i));
                } else if (message.at(i) == ' ') {
                    continue;
                } else {
                    throw std::runtime_error("Unknown symbol: " + std::to_string(message.at(i)));
                }
            }
        }

        if (tempNum != 0)
            operands.push(tempNum);
        if (!operators.empty())
            processOperator(operators, operands);

        return operands.top();
    }

private:
    void processOperator(std::stack<char> &operators, std::stack<int> &operands)
    {
        char op = operators.top();
        operators.pop();

        int right = operands.top();
        operands.pop();
        int left = operands.top();
        operands.pop();

        if (op == '+') {
            AddExpression add(new Expression(left), new Expression(right));
            int           value = add.interpret();
            operands.push(value);
        } else if (op == '-') {
            SubExcpression sub(new Expression(left), new Expression(right));
            int            value = sub.interpret();
            operands.push(value);
        }
    }
};